package com.zmn.oms.business.impl.messageV1.text;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.zmn.base.common.data.dubbo.interfaces.tags.TagsListRemoteService;
import com.zmn.base.pilot.common.dto.pilot.PilotCheckQuery;
import com.zmn.base.pilot.common.enums.PilotTypeEnum;
import com.zmn.base.price.common.dro.tariff.TariffDRO;
import com.zmn.base.price.dubbo.interfaces.tariff.TariffRemoteService;
import com.zmn.base.shortlink.common.enums.shortlink.ShortLinkTypeEnum;
import com.zmn.biz.engineer.common.dro.health.EngineerHealthLogoDRO;
import com.zmn.biz.engineer.dubbo.interfaces.health.EngineerHealthListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.amount.AmountUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.encode.EncodeUtil;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.business.impl.messageV1.common.AbstractBaseMessage;
import com.zmn.oms.business.interfaces.messageV1.common.MessageGetSendInfoService;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.model.dto.messageV1.SendMessageParams;
import com.zmn.oms.model.dto.messageV1.ShortUrlDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.work.OrderWork;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 类描述：
 *
 * @author yule
 * @date 2020/6/12 19:22
 */
@Slf4j
public abstract class AbstractMessageSendText extends AbstractBaseMessage {
    /**
     * 店铺订单详情页面
     */
    @Value("${oms.h5.detail.url:http://test2-h5.xiujiadian.com/wxuser/v2/%s/#/pages/order/detail?id=%s}")
    private String orderDetailUrl;

    /**
     * 品牌站啄木鸟订单详情页
     * 2.0 和非计价器订单
     */
    @Value("${oms.h5.zmn.detail.url:http://test2-h5.xiujiadian.com/wxuser/brand/#/subPackages/order/detail/index?id=%s}")
    protected String orderDetailH5Url;
    // 订单详情，非计价器3.0
    @Value("${oms.wechat.detail.url:/subPackages/order/detail/index?id=%s}")
    protected String orderDetailWechatUrl;
    // 商品详情页：/subPackages/product/detail?id=产品id      3.0
    @Value("${oms.wechat.detail.quotation3.url:/subPackages/product/detail?id=%s}")
    protected String productDetailWechatQuotation3Url;

    /**
     * 言而有信评价 url
     */
    @Value("${oms.user.yeyx.comment.url:http://test2-portal.xiujiadian.com/static/h5/page/common/order/comment/comment.html?orderId=%s}")
    protected String yeyxCommentH5Url;

    /**
     * 啄木鸟评价 url
     */
    @Value("${oms.user.comment.url:http://test2-h5.xiujiadian.com/wxuser/brand/#/subPackages/order/comment?id=%s}")
    private String commentH5Url;
    /**
     * 啄木鸟评价 url
     */
    @Value("${oms.wechat.user.comment.url:/subPackages/order/comment?id=%s}")
    protected String commentWechatUrl;

    // 购买会员地址
    @Value("${oms.h5.buyMemberUrl:https://d.zmn.cn/11uwX}")
    private String buyMemberUrl;

    @Autowired
    protected MessageGetSendInfoService messageGetSendInfoService;

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private TariffRemoteService tariffRemoteService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    protected TagsListRemoteService tagsListRemoteService;

    @DubboReference(version = com.zmn.biz.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerHealthListRemoteService engineerHealthListRemoteService;

    /**
     * 短信参数处理
     *
     * @param params
     */
    protected Map<String, String> handleSendParams(SendMessageParams params) {
        OrderWork orderWork = params.getOrderWork();
        OrderDetail orderDetail = params.getOrderDetail();

        // 不发送短信的 rule：上门、改约
        if (Objects.equals(MessageConsts.ZMN_MSG_RULEID_UPDATE_DUTYTIME, params.getRuleId()) ||
                Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_MASTER_VISIT, params.getRuleId())
        ) {
            return null;
        }

        // 取消订单发送短信处理
        if (Objects.equals(params.getNodeMark(), OrderLogConsts.ORDER_LOG_TYPE_CANCEL)) {
            boolean sendCancelMsg = this.checkSendCancelMsg(params);
            if (!sendCancelMsg) {
                return null;
            }
        }

        OrderProduct orderProduct = getProduct(params.getOrderId());

        Map<String, String> smsMap = new HashMap<>();

        // 2.工程师是否迟到减免
        boolean isLateOrder = NumberUtil.isNotNullOrZero(orderWork.getDiscountActivityId());
        // 3.判断是否非直营工程师
        boolean isNotAgent = messageGetSendInfoService.isNotAgent(orderWork.getMasterId());
        boolean isTempUser = params.isTempUser();

        // 确认节点短信，正式用户：根据下单时间判断，夜间段（20:00-24:00  0:00-8:00）发送短信，其余时间段不发短信
        int hh = Integer.parseInt(DateUtil.toString(orderWork.getReceiveTime(), "HH"));
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_ASSIGN, params.getRuleId()) ||
                Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_ASSIGN_NO_LOGIN, params.getRuleId())) {
            if (!isTempUser) {
                if(hh >= 8 && hh < 20){
                    logger.info("订单号【{}】确认节点短信不发送！正式用户-夜间段（20:00-24:00  0:00-8:00）发送短信，其余时间段不发短信 ruleId={}，phone={} ", params.getOrderId(), params.getRuleId(), params.getTelephone());
                    return null;
                }
            }

            // {$contact_time}：于xx时间上午
            // 下单时间为20:00-24:00：取下单日期+1天，传参文案【于xx日上午】
            // 下单时间为0:00-8:00：取下单日期，传参文案【于xx日上午】
            // 下单时间为8:00-20:00：传空
            //（格式：11月20日 19时20分）
            if(hh >= 20){
                smsMap.put("contact_time", String.format("于%s上午", DateUtil.toString(DateUtil.addDays(DateUtil.getNow(), 1), "dd日")));
            } else if(hh < 8) {
                smsMap.put("contact_time", String.format("于%s上午", DateUtil.getNowFormatted("dd日")));
            }
        }

        // 上门节点，计价器3.0 不发送
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_MASTER_VISIT, params.getRuleId()) &&
                Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE, orderWork.getServItemType())) {
            logger.info("订单号【{}】计价器3.0不推送 ruleId={}，phone={} ", params.getOrderId(), params.getRuleId(), params.getTelephone());
            return null;
        }

        // 通用内容
        if (StringUtils.isNotBlank(orderWork.getMasterName())) {
            smsMap.put("master_name", orderWork.getMasterName());
        }

        // 小号
        if (Objects.equals(orderDetail.getBindStatus(), OrderConsts.BIND_STATUS_BIND) &&
                StringUtils.isNotBlank(orderDetail.getBindTelephone())) {
            smsMap.put("privacy_trumpet", orderDetail.getBindTelephone());
        } else {
            smsMap.put("privacy_trumpet", "null");
        }

        smsMap.put("order_id", String.valueOf(params.getOrderId()));
        smsMap.put("product_name", orderProduct.getShowCategName());
        // 修改{$public_name}入参，川南环保→啄木鸟政企服务
        if(StringUtils.isNotBlank(params.getThirdAppName()) && params.getThirdAppName().indexOf("川南环保") >= 0){
            smsMap.put("public_name", "啄木鸟政企服务");
        } else {
            smsMap.put("public_name", StringUtils.replace(params.getThirdAppName(), "公众号", ""));
        }

        smsMap.put("user_telephone", orderDetail.getTelephone());
        smsMap.put("duty_time", DateUtil.toString(orderWork.getDutyTime(), "MM月dd日 HH时mm分"));
        smsMap.put("order_time", DateUtil.toString(orderWork.getReceiveTime(), "MM月dd日 HH时mm分"));

        // 提前付
        boolean isAdvancePay = false;

        // 判断提前付，先取订单，没有取试点配置
        if (Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_ADVANCE_PAY, orderWork.getServItemType())) {
            isAdvancePay = true;
        } else if (!Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE, orderWork.getServItemType())) {
            // 兼容老数据，上线一段时间后可以删除
            if (NumberUtil.isNotNullOrZero(orderProduct.getTariffId())) {
                // 判断价格表 1服务价格，2计价器价格，3提前支付价格
                ResponseDTO<TariffDRO> responseDTO = tariffRemoteService.getById(orderProduct.getTariffId());
                isAdvancePay = responseDTO.isSuccess() && Objects.nonNull(responseDTO.getData()) && Objects.equals(3, responseDTO.getData().getTariffType());
            } else {
                // 判断提前付试点
                PilotCheckQuery build = PilotCheckQuery
                        .builder()
                        .pilotTypeId(PilotTypeEnum.PAY_ADVANCE.getId())
                        .channelId(orderWork.getChannelId())
                        .cityId(orderWork.getCityId())
                        .servCategId(orderWork.getServCategId())
                        .categId(orderWork.getShowCategId())
                        .build();
                ResponseDTO<Boolean> responseDTO = pilotRemoteService.checkPilotByQuery(build);
                log.info("接单消息-提前付入参：{}, 出参：{}", JSON.toJSONString(orderWork), JSON.toJSONString(responseDTO));
                isAdvancePay = responseDTO.isSuccess() && responseDTO.getData();
            }
        }

        // 购买会员：分单、接单、计价器、节点微信消息
        if (!isAdvancePay) {
            //  {$pay_yesno} 增加判断逻辑（非提前付订单且非会员）
            //  --非提前付、非预付款订单 → 点击https://d.zmn.cn/0tqsz 开通Z+钻卡会员，享全年10大特权，一单回本
            //  --提前付、预付款 → 空
            if (Objects.isNull(orderWork.getPrepayTime()) && !Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_MEMBER)) {
                smsMap.put("pay_yesno", String.format("，点击 %s 开通Z+钻卡会员，享全年10大特权，一单回本", buyMemberUrl));
            }
        }

        // $meter_yesno：领单、上门
        //  {$meter_yesno}：
        // 提前付--> 传空
        // 非提前付
        //      计价器2.0-->   ，为保障您的权益，请认准计价器报价
        //      计价器3.0-->   ，点击链接查看服务价格表
        // 非计价器-->   传空
        if (isAdvancePay) {
            // 提前付工单
            // smsMap.put("meter_yesno", "，请耐心等候，如有特殊情况请及时与师傅沟通");
            smsMap.put("meter_yesno", "null");
        } else if (Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_FAULT, orderWork.getServItemType())) {
            // 计价器2.0
            smsMap.put("meter_yesno", "，为保障您的权益，请认准计价器报价");
        } else if (Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE, orderWork.getServItemType())) {
            // 计价器3.0
            smsMap.put("meter_yesno", "，点击链接查看服务价格表");
        }

        // 是否有迟到补偿
        if (isLateOrder) {
            smsMap.put("late_yesno", "，若上门延误，服务费减免20元");
        }

        // 非直营工程师不发送价格
        List<Integer> completeRules = Lists.newArrayList(MessageRuleIdConsts.ZMN_MSG_RULEID_COMPLETE, MessageRuleIdConsts.CNHB_MSG_RULEID_COMPLETE);
        if (completeRules.contains(params.getRuleId())) {
            smsMap.put("charge_warranty", "null");
        }

        if (completeRules.contains(params.getRuleId()) && isNotAgent) {
            // 服务价格
            double totalAmount = MoneyUtil.parseToYuan(orderWork.getTotalAmount());
            // 服务价格
            String totalAmountStr = String.format("%.2f元", totalAmount);
            if (!NumberUtil.isNullOrZero(orderWork.getDiscountAmount())) {
                double disAmount = AmountUtil.fen2Yuan(orderWork.getDiscountAmount()).doubleValue();
                totalAmountStr = String.format("%.2f元（已优惠：%.2f元）", totalAmount, disAmount);
            }

            String warrantyStr = "";
            String warrantyCode = messageGetSendInfoService.checkWarrantyAndGetWarrantyCode(params.getOrderId());
            if (StringUtils.isNotBlank(warrantyCode)) {
                warrantyStr = "，记得领取电子保修卡";
            }

            String chargeWarranty = String.format("，费用%s%s", totalAmountStr, warrantyStr);
            smsMap.put("charge_warranty", chargeWarranty);
        }

        // 规则特殊处理：言而有信保内订单
        if (Objects.equals(MessageRuleIdConsts.YEYX_MSG_RULEID_MASTER_VISIT_TYPE_IN, params.getRuleId()) ||
                Objects.equals(MessageRuleIdConsts.YEYX_MSG_RULEID_SPECIAL_CHANNEL_MASTER_VISIT_TYPE_IN, params.getRuleId())) {
            String featureCode = EncodeUtil.getFeatureCode(orderWork.getWorkId(), 4);
            smsMap.put("complete_code", featureCode);
        }

        // 退款成功
        if (Objects.equals(MessageConsts.ZMN_MSG_RULEID_SERVICE_REFUND_SUCCESS, params.getRuleId())) {
            Double refundAmount = null;
            if (StringUtil.isBlank(params.getRemark())) {
                refundAmount = MoneyUtil.parseToYuan(orderWork.getRefundAmount() + Math.abs(Optional.ofNullable(orderWork.getDiscountPrepayAmount()).orElse(0)));
            }else {
                Map<String,Integer> map = JSON.parseObject(params.getRemark(), new TypeReference<HashMap<String, Integer>>() {
                });
                Integer refundAmountTemp = map.get("refundAmount");
                refundAmountTemp = Optional.ofNullable(refundAmountTemp).orElse(0);
                refundAmount = MoneyUtil.parseToYuan(refundAmountTemp);
            }

            if (NumberUtil.isNullOrZero(refundAmount)) {
                return null;
            }
            smsMap.put("refund amount", String.format("%.2f", refundAmount));
        }

        // 工程师体温 只有 ruleId 等于 10080 处理 master_temperature
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_TAKE, params.getRuleId())) {
            double masterTemperature = ThreadLocalRandom.current().nextDouble(36.0, 37.0);
            smsMap.put("master_temperature", String.format("%.1f", masterTemperature));
        }
        // 工程师健康信息
        if(Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_TAKE, params.getRuleId()) || Objects.equals(MessageConsts.ZMN_MSG_RULEID_RETAKE, params.getRuleId())){
            String masterHealthInfo = "null";
            if(NumberUtil.isNotNullOrZero(orderWork.getMasterId())){
                ResponseDTO<EngineerHealthLogoDRO> healthLogoResponseDTO= engineerHealthListRemoteService.getDisplayHealthLogoByEngineerId(orderWork.getMasterId());
                if(Objects.nonNull(healthLogoResponseDTO) && healthLogoResponseDTO.isSuccess() && Objects.nonNull(healthLogoResponseDTO.getData())){
                    if(!healthLogoResponseDTO.getData().getGetVaccine() && healthLogoResponseDTO.getData().getBodyTemperature()){
                        masterHealthInfo = "（工程师体温正常）";
                    }
                    if(healthLogoResponseDTO.getData().getGetVaccine() && healthLogoResponseDTO.getData().getBodyTemperature()){
                        masterHealthInfo = "（工程师已接种疫苗，体温正常）";
                    }
                }
            }
            smsMap.put("master_health_info", masterHealthInfo);
        }

        // 默认参数处理
        super.setParamsDefaultIfNull(smsMap);

        // 跳转链接处理
        this.handleShortUrlParams(params, smsMap);

        return smsMap;
    }

    /**
     * url处理
     *
     * @param params
     * @param smsMap
     */
    private void handleShortUrlParams(SendMessageParams params, Map<String, String> smsMap) {
        ShortUrlDTO shortUrlDTO = ShortUrlDTO.builder()
                .orderId(params.getWorkId())
                .ruleId(params.getRuleId())
                .build();

        if (Objects.equals(GlobalConsts.PLAT_MARK_ZMN, params.getPlat())) {
            shortUrlDTO.setShortLinkType(ShortLinkTypeEnum.MINIPROGRAMS_SHORTLINK.getKey());
            if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_COMPLETE, params.getRuleId())) {
                shortUrlDTO.setMiniProgramsLink(String.format(commentWechatUrl, params.getOrderId()));
            } else {
                shortUrlDTO.setMiniProgramsLink(String.format(orderDetailWechatUrl, params.getOrderId()));
            }
        } else {
            if (Objects.equals(MessageRuleIdConsts.YEYX_MSG_RULEID_COMPLETE_TYPE_IN, params.getRuleId())) {
                // 评价详情页面
                shortUrlDTO.setLink(String.format(yeyxCommentH5Url, params.getOrderId()));
            } else {
                shortUrlDTO.setLink(String.format(orderDetailH5Url, params.getOrderId()));
            }
        }
        smsMap.put("short_link", messageGetSendInfoService.getShortUrl(shortUrlDTO));
    }

    /**
     * 检查是否需要发送取消短信
     *
     * @param params
     * @return
     */
    private boolean checkSendCancelMsg(SendMessageParams params) {
        OrderWork orderWork = params.getOrderWork();
        OrderDetail orderDetail = params.getOrderDetail();

        // 当行政子公司为：家修匠 且没有预付款 且订单状态：已录入、已确认、已分单 且没有预付款 且是人工取消
        if (Objects.equals(orderDetail.getGridCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID)
                && NumberUtil.isNullOrZero(orderWork.getPrepayAmount())
                && orderWork.getStatus() < OrderStatusConsts.WORK_STATUS_DISTRIBUTE
                && Objects.equals(orderWork.getCancelerType(), com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_STAFF)
        ) {
            return true;
        }

        // 执行服务商是无法承接线索，或者行政服务商是无法服务  需要发送短信
        boolean isUnableSpCompany = Objects.equals(orderWork.getManageCompanyId(), CompanyConsts.ZMN_JXJ_MANAGE_COMPANY_ID) ||
                Objects.equals(CompanyConsts.ZMN_UNABLE_SERVICE_MANAGE_COMPANY_ID, orderDetail.getGridManageCompanyId());
        if (isUnableSpCompany) {
            return true;
        }

        // 系统取消需要发送短信
        if (Objects.equals(orderWork.getCancelerType(), GlobalConsts.OPERATE_USER_TYPE_SYSTEM)) {
            return true;
        }

        logger.info("订单号【{}】不发送取消短信 ruleId={}，phone={} ", params.getOrderId(), params.getRuleId(), params.getTelephone());
        return false;
    }

}
